package com.web.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.lang.reflect.Method;

/**
 * @author FDjavaone
 * @date 2017/9/20
 */
@Component
@Aspect
@Slf4j
public class PermissionAspect {
    @Resource(name = "stringRedisTemplate")
    private StringRedisTemplate stringRedisTemplate;

    @Pointcut("@annotation(com.web.annotation.UserAccess)")
    private void point() {

    }


    @Around("point()")
    public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("前置通知");
        String methodName = joinPoint.getSignature().getName();
        Object target = joinPoint.getTarget();
        //得到拦截的方法
        Method method = getMethodByClassAndName(target.getClass(), methodName);
        Object[] args = joinPoint.getArgs();
        HttpServletRequest request = (HttpServletRequest) args[1];
        HttpServletResponse response = (HttpServletResponse) args[2];
        String token = request.getHeader("token");
        log.info("前置通知  token:" + token + "调用方法:" + method);

        String user = "";
        if (token != null) {
            user = stringRedisTemplate.opsForValue().get(token);
        }
        log.info("取到的用户信息：" + user);

        if ("".equals(user) || user == null) {
            log.info("验证不通过！");
            response.setContentType("application/json;charset=UTF-8");
            OutputStream out = response.getOutputStream();
            out.write("{\"status\":999999,\"message\":\"该账号已在其他设备上登录，请确定是否本人操作，及时修改密码！\"}".getBytes("utf-8"));
            return null;
        }

        return joinPoint.proceed();

    }


    /**
     * 根据类和方法名得到方法
     */
    public Method getMethodByClassAndName(Class c, String methodName) {
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                return method;
            }
        }
        return null;
    }
}
